import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

// 游戏主面板
public class GamePanel extends JPanel implements KeyListener {
    private final BufferedImage image; // 主图片
    private final BackgroundImage background; // 背景图片
    private final Dinosaur golden; // 恐龙
    private final Graphics2D g2; // 主图片绘图对象
    private int addObstacleTimer = 0; // 添加障碍计时器
    private boolean finish = false; // 游戏结束标志
    private final ArrayList<Obstacle> list = new ArrayList<>(); // 障碍集合
    public boolean isPaused = false;
    int score = 0; // 得分
    int scoreTimer = 0; // 分数计时器
    int theme;

    public GamePanel(int theme) {
        this.theme = theme;
        this.setOpaque(false); // 确保游戏面板的背景是透明的
        setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));

        // 获取主图片绘图对象
        image = new BufferedImage(800, 300, BufferedImage.TYPE_INT_BGR);
        g2 = image.createGraphics();

        // 创建背景和恐龙对象
        background = new BackgroundImage();
        if (theme == 0) golden = new Dinosaur();
        else golden = new Kun();
        list.add(Obstacle.getObstacle());

        // 创建和启动刷新线程
        FreshThread t = new FreshThread(this);
        t.start();
    }

    // 绘制主图片
    private void paintImage() {
        background.roll(); // 背景图片开始滚动
        golden.move(); // 恐龙开始移动
        g2.drawImage(background.image, 0, 0, this); // 绘制滚动背景
        if (addObstacleTimer == 1500) {
            if (Math.random() * 100 > 20) {
                list.add(Obstacle.getObstacle());
            }
            addObstacleTimer = 0;
        }

        for (int i = 0; i < list.size(); i++) { // 遍历障碍集合
            Obstacle o = list.get(i); // 获取障碍对象
            if (o.isLive()) { // 如果是有效障碍
                o.move();
                drawObstacle(o);
                // 如果恐龙头脚碰到障碍
                if (o.getBounds().intersects(golden.getFootBounds())
                        || o.getBounds().intersects(golden.getHeadBounds())) {
                    Sound.hit(); // 播放撞击声音
                    gameOver(); // 游戏结束
                }
            } else { // 如果不是有效障碍
                list.remove(i); // 删除此障碍
                i--; // 循环变量前移
            }
//            drawBounds(o);
        }
        g2.drawImage(golden.image, golden.x, golden.y, this); // 绘制恐龙
//        drawDragonBounds();
        if (scoreTimer >= 500) { // 每过500毫秒
            score += 10; // 加十分
            // 每次加一百分加速
            if (score % 200 == 0) {
                FreshThread.addSpeed();
            }
            scoreTimer = 0; // 重新计时
        }
        // 绘制分数
        g2.setColor(Color.BLACK); // 使用黑色
        g2.setFont(new Font("黑体", Font.BOLD, 24)); // 设置字体
        g2.drawString(String.format("%06d", score), 700, 30); // 绘制分数

        addObstacleTimer += FreshThread.FRESH; // 障碍计时器递增
        scoreTimer += FreshThread.fresh; // 分数计时器递增
    }

    public void drawObstacle(Obstacle b) {
        if (b.image == b.basketball) {
            Basketball o = (Basketball) b;
            // 保存当前图形的变换
            AffineTransform old = g2.getTransform();
            // 围绕中心旋转图像
            g2.rotate(Math.toRadians(o.getAngle()), o.x + (double) o.image.getWidth() / 2, o.y + (double) o.image.getHeight() / 2);
            g2.drawImage(o.image, o.x, o.y, this);
            // 恢复原始变换
            g2.setTransform(old);
        } else g2.drawImage(b.image, b.x, b.y, this); // 绘制障碍
    }

    public void paused() {
        isPaused = true;
    }

    public void resume() {
        isPaused = false;
    }

    // 重写绘制组件方法
    public void paint(Graphics g) {
        super.paint(g);
        paintImage(); // 绘制主图片内容
        g.drawImage(image, 0, 0, this);
    }

    // 游戏是否结束
    public boolean isFinish() {
        return finish;
    }

    // 使游戏结束
    public void gameOver() {
        ScoreRecorder.addNewScore(score); // 记录当前分数
        finish = true;
    }

    // 实现按下键盘按键方法
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode(); // 获取按下的按键值
        if (code == KeyEvent.VK_SPACE || code == KeyEvent.VK_UP) { // 如果是空格或者上键
            golden.jump(); // 恐龙跳跃
        }
        // 按下向下
        if (code == KeyEvent.VK_DOWN) {
            golden.down();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // 如果松开空格
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            golden.up();
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    public void drawBounds(Obstacle o) {
        if (o == null) return;
        g2.setColor(Color.RED);
        Rectangle rectangle = o.getBounds();
        if (o.image == o.meteorite) {
            g2.drawRect(o.x, o.y, o.image.getWidth() - 10, o.image.getHeight());
        } else {
            g2.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
        }
    }

    public void drawDragonBounds() {
        g2.setColor(Color.RED);
        if (golden.getDownState()) g2.drawRect(golden.x + 10, golden.y + 10, 70, 25);
        else {
            Rectangle rectangle = golden.getFootBounds();
            g2.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
            Rectangle headBounds = golden.getHeadBounds();
            g2.drawRect(headBounds.x, headBounds.y, headBounds.width, headBounds.height);
        }
    }
}